/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ggsoft.timetracker.service.impl;

import com.ggsoft.timetracker.dao.TimeTrackerDao;
import com.ggsoft.timetracker.domain.Department;
import com.ggsoft.timetracker.domain.Employee;
import com.ggsoft.timetracker.domain.Timecard;
import com.ggsoft.timetracker.service.TimeTrackerService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import org.appfuse.dao.GenericDao;
import org.appfuse.dao.UserDao;
import org.appfuse.model.User;
import org.appfuse.service.impl.GenericManagerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author giovanella
 * @date May 17, 2014
 */
@Service
public class TimeTrackerServiceImpl extends GenericManagerImpl<Timecard, Long> implements TimeTrackerService {

    private TimeTrackerDao timeTrackerDao;
    private UserDao userDao;
    private GenericDao<Department, Long> departmentDao;

    public TimeTrackerServiceImpl() {
    }

    @Autowired
    public void setTimeTrackerDao(TimeTrackerDao timeTrackerDao) {
        this.timeTrackerDao = timeTrackerDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setDepartmentDao(GenericDao<Department, Long> departmentDao) {
        this.departmentDao = departmentDao;
    }

    @Override
    @Transactional
    public void punchTimeCard(User requestUser, String status, String reason, String station) {
        Timecard card = null;
        User user = userDao.get(requestUser.getId());
        if (user != null) {
            if (status.equals("IN")) {
                card = timeTrackerDao.findLastTimecard(user);
                if (card != null) {
                    card.setLogoutTime(new Date());
                    card.setReason(reason);
                    card.setLogoutStation(station);
                    card.setModifiedOn(new Date());
                    card.setModifiedBy(user);

                    user.setStatus("OUT");
                    long diff = card.getLogoutTime().getTime() - card.getLoginTime().getTime();
                    long diffMinutes = diff / (60 * 1000);
                    Long diffHours = diff / (60 * 60 * 1000);
                    Long diffMinHour = diffMinutes - diffHours * 60;
                    Double totalMins = (diffMinHour.doubleValue() * 100 / 60) / 100;
                    Double totalHours = diffHours.doubleValue() + totalMins;
//                    System.out.println("Diff: " + diffHours + ":" + diffMinutes + "");
                    card.setTotalHours(totalHours);
                }
            } else {
                card = new Timecard();
                card.setUser(user);
                card.setDate(new Date());
                card.setLoginTime(new Date());
                card.setLoginStation(station);
                card.setCreateOn(new Date());
                card.setCreatedBy(user);
                user.setStatus("IN");
            }

            if (card != null) {
                userDao.save(user);
                timeTrackerDao.storeTimeCard(card);
            }
        }
    }

    @Override
    public void fixTimeCard(Timecard timeCard) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void findTimeCardsPerEmployee(Employee employee) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Employee getEmployeeById(Long id) {
        return null;
    }

    @Override
    public Employee getEmployeeByUser(User user) {
        return null;
    }

    @Override
    public List<Department> getDepartmentList() {
        return departmentDao.getAll();
    }

    @Override
    @Transactional
    public List<Timecard> findTimecards(User user, String status, Date date) {
        return timeTrackerDao.findTimecards(user, status, date);
    }

    @Override
    @Transactional
    public Timecard findTimecard(Long id) {
        return timeTrackerDao.get(id);
    }

    @Override
    @Transactional
    public void saveTimecard(Timecard card) {
        if (card.getLogoutTime() != null && card.getLoginTime() != null) {
            long diff = card.getLogoutTime().getTime() - card.getLoginTime().getTime();
            long diffMinutes = diff / (60 * 1000);
            Long diffHours = diff / (60 * 60 * 1000);
            Long diffMinHour = diffMinutes - diffHours * 60;
            Double totalMins = (diffMinHour.doubleValue() * 100 / 60) / 100;
            Double totalHours = round(diffHours.doubleValue() + totalMins, 2);

            card.setTotalHours(totalHours);
        }
        timeTrackerDao.save(card);
    }

    public static double round(double value, int places) {
        if (places < 0) {
            throw new IllegalArgumentException();
        }

        BigDecimal bd = new BigDecimal(value);
        bd = bd.setScale(places, RoundingMode.HALF_UP);
        return bd.doubleValue();
    }

    public boolean validateIp(String currentIp, String allowedIps) {
        boolean valid = false;
        // Ex. 192.168.0.*
        if (allowedIps != null && !allowedIps.equals("")) {
            String[] validIps = allowedIps.split(",");

            for (String ip : validIps) {
                String validIp = ip.trim();
                if (validIp.equals("*")) {
                    valid = true;
                    break;
                } else if (validIp.endsWith("*")) {
                    valid = true;
                    validIp = validIp.substring(0, validIp.indexOf("*") - 1);

                    String[] numbersValidIp = validIp.replace(".", "/").split("/");
                    String[] numbersCurrentIp = currentIp.replace(".", "/").split("/");
                    System.out.println("validIp; " + validIp + "; currentIp: " + currentIp);
                    for (int i = 0; i < numbersValidIp.length; i++) {
                        System.out.println("i: " + i + "; numbersValidIp " + numbersValidIp[i] + "; numbersCurrentIp: " + numbersCurrentIp[i]);
                        if (!numbersValidIp[i].equals(numbersCurrentIp[i])) {
                            valid = false;
                            break;
                        }
                    }
                } else {
                    if (validIp.equals(currentIp)) {
                        System.out.println("validIp; " + validIp + "; currentIp" + currentIp);
                        valid = true;
                        break;
                    }
                }
            }
        }

        return valid;
    }
}
